/**
 * 
 */
package ar.edu.utn.frsf.cidisi.ginet.generation.upcolbpip2cginet.elementstemplate;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.pnml.tools.epnk.pnmlcoremodel.Coordinate;
import org.pnml.tools.epnk.pnmlcoremodel.NodeGraphics;
import org.pnml.tools.epnk.pnmlcoremodel.PnmlcoremodelFactory;
import org.pnml.tools.epnk.pntypes.hlpng.pntd.hlpngdefinition.Declaration;

import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Arc;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Page;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Place;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.RefPlace;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Transition;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.BusinessMessage;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionProtocolElement;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.Termination;


/**
 * @author Neri
 *
 */
public class InteractionProtocolStructure extends ChoreographyStructure {
	
	private EList<Declaration> ginetDeclarations;
	
	
	
	public InteractionProtocolStructure(EList<InteractionProtocolElement> elementList, EList<Declaration> ginetDeclarations){		
		super();
		this.elementsIP = elementList;
		
		this.fillVarDeclAndNameSort(ginetDeclarations);
		
		this.ginetDeclarations = ginetDeclarations;
		
	}
	
	public Page createInteractionProtocol(int pos , EList<BusinessMessage> bMessages){
		EList<Page> pages = new BasicEList<Page>();

		Page pageReturn = ChoreographyStructure.createPage("InteractionProtocol", 4, 1, "InteractionProtocol", -9, -39);
	
		EList<BusinessMessage> messages = this.getBusinessMessagesForInteractionProtocol(bMessages);
		
		Place placeTermination = this.createPlace("Termination", 240 ,
				(float) 114.5, "Termination", -4, -9,
				this.getVarDec("gi"), 6, 21, false, "1");
		
		InteractionProtocolElement element = this.getBeginElement(this.elementsIP);
		
		int i = 0;
		int k = 1;
		Transition transition = null;
		RefPlace refTermination = null;
		while (element != null) {
			Place place = null;
			Place place2 = null;

			Arc arc = null;
			Arc arc1 = null;

			Page page = null;
			if (element instanceof Termination) {
				if(element.getSuccessor() != null){
					refTermination = this.createRefPlace("Termination"+i,
							(80 + (320 * i)), (float) 230, "Termination"+i, -4,
							-9, "1", placeTermination);
					pageReturn.getObject().add(refTermination);
					if (transition != null) {
						Arc arcT = this.createArc("", this.getVarDec("gi"), -9, -19,
								transition, refTermination);
						pageReturn.getObject().add(arcT);
					}
					i--;
					k--;
				}else{
					
					NodeGraphics graphics = PnmlcoremodelFactory.eINSTANCE
							.createNodeGraphics();

					Coordinate coordinate = PnmlcoremodelFactory.eINSTANCE
							.createCoordinate();

					coordinate.setX(40);
					coordinate.setY(40);

					graphics.setDimension(coordinate);

					Coordinate coordinate1 = PnmlcoremodelFactory.eINSTANCE
							.createCoordinate();

					coordinate1.setX(80 + (320 * (i)));
					coordinate1.setY((float) 114.5);
					
					graphics.setPosition(coordinate1);
					
					placeTermination.setGraphics(graphics);	
					if (transition != null) {
						Arc arcT = this.createArc("", this.getVarDec("gi"), -9, -19,
								transition, placeTermination);
						pageReturn.getObject().add(arcT);
					}				
					
					pageReturn.getObject().add(placeTermination);
				}
			
			} else {
				place = this.createPlace("InIP" + k, (80 + (320 * (i))),
						(float) 114.5, "InIP" + k, -4, -9,
						this.getVarDec("gi"), 6, 21, true, "1");
				if (transition != null && element.getPredecessor() != null) {
					if(!(element.getPredecessor() instanceof Termination)){
						arc = this.createArc("", this.getVarDec("gi"), -9, -19,
								transition, place);
					}
				}

				if (element.getSuccessor() != null) {
					place2 = this.createPlace("OutIP" + k, (240 + (320 * (i))),
							(float) 114.5, "OutIP" + k, -4, -9,
							this.getVarDec("gi"), 6, 21, false, "1");
					transition = this.createTransition("IPTransition" + k,
							(320 + (320 * i)), (float) 114.5, "IPTransition"
									+ k, -9, -4, "1", "1", null);
					arc1 = this.createArc("", this.getVarDec("gi"), -9, -19,
							place2, transition);
				}else{
					NodeGraphics graphics = PnmlcoremodelFactory.eINSTANCE
							.createNodeGraphics();

					Coordinate coordinate = PnmlcoremodelFactory.eINSTANCE
							.createCoordinate();

					coordinate.setX(40);
					coordinate.setY(40);

					graphics.setDimension(coordinate);

					Coordinate coordinate1 = PnmlcoremodelFactory.eINSTANCE
							.createCoordinate();

					coordinate1.setX(240 + (320 * (i)));
					coordinate1.setY((float) 114.5);
					
					graphics.setPosition(coordinate1);
					
					placeTermination.setGraphics(graphics);	
					place2 = placeTermination;
				}

				if (element instanceof BusinessMessage) {
					if(messages.contains(element)){
						page = this.getPageForElement(element, k, place, place2,
								ginetDeclarations, placeTermination, bMessages);
					}					
				} else {
					page = this.getPageForElement(element, k, place, place2,
							ginetDeclarations, placeTermination, bMessages);
				}

				if (page != null) {

					NodeGraphics graphics = PnmlcoremodelFactory.eINSTANCE
							.createNodeGraphics();

					Coordinate coordinate = PnmlcoremodelFactory.eINSTANCE
							.createCoordinate();

					coordinate.setX(40);
					coordinate.setY(40);

					graphics.setDimension(coordinate);

					Coordinate coordinate1 = PnmlcoremodelFactory.eINSTANCE
							.createCoordinate();

					coordinate1.setX((160 + (320 * i)));
					coordinate1.setY((float) 114.5);

					graphics.setPosition(coordinate1);

					page.setGraphics(graphics);

					pages.add(page);

					if (place != null) {
						pageReturn.getObject().add(place);
					}
					if (arc != null) {
						pageReturn.getObject().add(arc);
					}
					if (arc1 != null) {
						pageReturn.getObject().add(arc1);
					}
					if (place2 != null) {
						pageReturn.getObject().add(place2);
					}
					if (transition != null) {
						pageReturn.getObject().add(transition);
					}
				}
			}
			i++;
			k++;
			element = element.getSuccessor();
		}

		pageReturn.getObject().addAll(pages);
		
		return pageReturn;
	}

	public EList<Declaration> getGinetDeclarations(){
		return this.ginetDeclarations;
	}
}
